package com.yq.interview.study.thread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName ReenterLockDemo
 * @Description 可重入锁
 *
 * 指同一个线程外层函数获得锁后，内层递归函数仍能获取该锁的代码
 * 在同一个线程在外层方法获取锁时，在进入内层会自动获取锁
 * 即线程可以进入任意一个它已经拥有锁同步着的所有代码块
 *
 * @Author yaoqiang
 * @Date 2020/11/19 9:26
 * @Version 1.0
 */
public class ReenterLockDemo {
    public static void main(String[] args) {
        Phone phone=new Phone();

        new Thread(()->{
            phone.sendMsg();

        },"t1").start();
        new Thread(()->{
            phone.sendMsg();

        },"t2").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t3=new Thread(phone);
        Thread t4=new Thread(phone);
        t3.start();
        t4.start();
    }
}


class Phone  implements  Runnable{
    public synchronized void sendMsg(){
        System.out.println(Thread.currentThread().getName()+"  Phone  sendMsg");
        sendEmail();
    }
    public synchronized  void sendEmail(){
        System.out.println(Thread.currentThread().getName()+"****Phone  sendEmail");
    }


    @Override
    public void run() {
        get();
    }

    Lock lock=new ReentrantLock();
    private void get() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"。。。get()");
            set();
        }finally {
            lock.unlock();
        }
    }

    private void set() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"。。。set()");
        }finally {
            lock.unlock();
        }
    }
}